<template>
  <div class="echarts" :style="[{
  width:mWidth,
  height:mHeight
  }]">
  </div>
</template>

<style>

</style>

<script>
  import echarts from 'echarts/lib/echarts'
  import debounce from 'lodash/debounce'
  import { addListener, removeListener } from 'resize-detector'
  import Vue from 'vue'
  import 'echarts/lib/chart/line'
  import  * as config from './options'
  // enumerating ECharts events for now
  const EVENTS = [
    'legendselectchanged',
    'legendselected',
    'legendunselected',
    'legendunscroll',
    'datazoom',
    'datarangeselected',
    'timelinechanged',
    'timelineplaychanged',
    'restore',
    'dataviewchanged',
    'magictypechanged',
    'geoselectchanged',
    'geoselected',
    'geounselected',
    'pieselectchanged',
    'pieselected',
    'pieunselected',
    'mapselectchanged',
    'mapselected',
    'mapunselected',
    'axisareaselected',
    'focusnodeadjacency',
    'unfocusnodeadjacency',
    'brush',
    'brushselected',
    'rendered',
    'finished',
    'click',
    'dblclick',
    'mouseover',
    'mouseout',
    'mousedown',
    'mouseup',
    'globalout'
  ]

  export default {
    props: {
      options: Object,
      theme: [String, Object],
      initOptions: Object,
      group: String,
      autoResize: Boolean,
      watchShallow: Boolean,
      type:String,
      mHeight:{
        type:String,
        default(){
          return document.documentElement.clientHeight + 'px';
        }
      },
      mWidth:{
        type:String,
        default(){
          return document.documentElement.clientWidth + 'px';
        }
      }
    },
    data () {
      return {
        chart: null,
        lastArea: 0
      }
    },
    computed: {
      // Only recalculated when accessed from JavaScript.
      // Won't update DOM on value change because getters
      // don't depend on reactive values
      width: {
        cache: false,
        get () {
          return this.delegateGet('width', 'getWidth')
        }
      },
      height: {
        cache: false,
        get () {
          return this.delegateGet('height', 'getHeight')
        }
      },
      isDisposed: {
        cache: false,
        get () {
          return !!this.delegateGet('isDisposed', 'isDisposed')
        }
      },
      computedOptions: {
        cache: false,
        get () {
          return this.delegateGet('computedOptions', 'getOption')
        }
      }
    },
    watch: {
      group (group) {
        this.chart.group = group
      }
    },
    methods: {
      mergeOptions (options, notMerge, lazyUpdate) {
        this.delegateMethod('setOption', options, notMerge, lazyUpdate)
      },
      appendData (params) {
        this.delegateMethod('appendData', params)
      },
      resize (options) {
        this.delegateMethod('resize', options)
      },
      dispatchAction (payload) {
        this.delegateMethod('dispatchAction', payload)
      },
      convertToPixel (finder, value) {
        return this.delegateMethod('convertToPixel', finder, value)
      },
      convertFromPixel (finder, value) {
        return this.delegateMethod('convertFromPixel', finder, value)
      },
      containPixel (finder, value) {
        return this.delegateMethod('containPixel', finder, value)
      },
      showLoading (type, options) {
        this.delegateMethod('showLoading', type, options)
      },
      hideLoading () {
        this.delegateMethod('hideLoading')
      },
      getDataURL (options) {
        return this.delegateMethod('getDataURL', options)
      },
      getConnectedDataURL (options) {
        return this.delegateMethod('getConnectedDataURL', options)
      },
      clear () {
        this.delegateMethod('clear')
      },
      dispose () {
        this.delegateMethod('dispose')
      },
      delegateMethod (name, ...args) {
        if (!this.chart) {
          Vue.util.warn(`Cannot call [${name}] before the chart is initialized. Set prop [options] first.`, this)
          return
        }
        return this.chart[name](...args)
      },
      delegateGet (name, method) {
        if (!this.chart) {
          Vue.util.warn(`Cannot get [${name}] before the chart is initialized. Set prop [options] first.`, this)
        }
        return this.chart[method]()
      },
      getArea () {
        return this.$el.offsetWidth * this.$el.offsetHeight
      },
      init () {

        if(this.options.status != 'start') return ;
        if (this.chart) {
          return
        }

        let chart = echarts.init(this.$el, this.theme, this.initOptions)

        if (this.group) {
          chart.group = this.group
        }

        chart.setOption(this.options, true)

        // expose ECharts events as custom events
        EVENTS.forEach(event => {
          chart.on(event, params => {
            this.$emit(event, params)
          })
        })

        if (this.autoResize) {
          this.lastArea = this.getArea()
          this.__resizeHandler = debounce(() => {
            if (this.lastArea === 0) {
              // emulate initial render for initially hidden charts
              this.mergeOptions({}, true)
              this.resize()
              this.mergeOptions(this.options, true)
            } else {
              this.resize()
            }
            this.lastArea = this.getArea()
          }, 100, { leading: true })
          addListener(this.$el, this.__resizeHandler)
        }

        this.chart = chart
      },
      destroy () {
        if (this.autoResize) {
          removeListener(this.$el, this.__resizeHandler)
        }
        this.dispose()
        this.chart = null
      },
      refresh () {
        this.destroy()
        this.init()
      }
    },
    created () {
      if(this.type){
        this.$emit('EchatsConfig',config[this.type])
      }
      this.$watch('options', options => {
        if (!this.chart && options) {
          this.init()
        } else {
          this.chart.setOption(this.options, true)
        }
      }, { deep: !this.watchShallow })

      let watched = ['theme', 'initOptions', 'autoResize', 'watchShallow']
      watched.forEach(prop => {
        this.$watch(prop, () => {
          this.refresh()
        }, { deep: true })
      })
    },
    mounted () {

      if (this.options) {
        this.init()
      }
    },
    activated () {
      if (this.autoResize) {
        this.chart && this.chart.resize()
      }
    },
    beforeDestroy () {
      if (!this.chart) {
        return
      }
      this.destroy()
    },
    connect (group) {
      if (typeof group !== 'string') {
        group = group.map(chart => chart.chart)
      }
      echarts.connect(group)
    },
    disconnect (group) {
      echarts.disConnect(group)
    },
    registerMap (mapName, geoJSON, specialAreas) {
      echarts.registerMap(mapName, geoJSON, specialAreas)
    },
    registerTheme (name, theme) {
      echarts.registerTheme(name, theme)
    },
    graphic: echarts.graphic
  }
</script>
